package com.foreveross.proxyip.core.redis;

import redis.clients.jedis.Transaction;

import com.foreveross.proxyip.util.SerializeUtil;
import com.sun.istack.NotNull;

public class IpStoreMap {

	private static IpStoreMap instance = null ;
	RedisManager redisManager = RedisManager.getInstance();
	
//	JedisPool pool = null;
//	
////	public Long storeTimeOut = Long.parseLong(BaseCode.getValue("RDS_TIMEOUT"));
//	
//	 public Jedis getRedis(){
//		return pool.getResource();
//	 }
//	 
	 
	
	private IpStoreMap() {
//		this.pool =  this.pool = RedisManager.getInstance().getJedisPool(); 
	}

	public boolean containsKey(final String key) throws PiRedisExecption {
//		return this.containsKey(null, key);
		return new RedisExecutor<Boolean>() {
			@Override
			public Boolean run() throws Exception {
				Boolean b = jedis.exists(key.getBytes());
				return b;
			}
		}.exec();
	}
	
	public static IpStoreMap getIntance(){
		if(instance==null){
			instance = new IpStoreMap();
		}	
		return instance;
	}
	
//	public boolean containsKey(Jedis redis, String key) {
//		
//		
//		
//		try{
//			if(redis==null){
//				redis = getRedis();
//			}
//			Boolean b = redis.exists(key.getBytes());
//			return b;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
//	}


	public AbstractStoreBean get(final String key) throws Exception {
		return new RedisExecutor<AbstractStoreBean>() {
			@Override
			public AbstractStoreBean run() throws Exception {
				return (AbstractStoreBean) SerializeUtil.unserialize(jedis.get(key.getBytes()));
			}
		}.exec();
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			return (AbstractStoreBean) SerializeUtil.unserialize(redis.get(key.getBytes()));
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}
/**
 * 这个方法只能出现在验证线程里面
 * @param key
 * @param value
 * @return
 * @throws Exception
 */
	public String update(final String key,final AbstractStoreBean bean) throws PiRedisExecption {
		return new RedisExecutor<String>() {
			@Override
			public String run() throws Exception {
				String result = null;
				if(jedis.exists(key.getBytes())){
					if(bean.getUsingKeys().isEmpty()){//无效对象
						if(jedis.exists(key.getBytes())){
							jedis.del(key.getBytes());
						}
					}else{
						bean.setCheckTime(System.currentTimeMillis());
						result = jedis.set(key.getBytes(), SerializeUtil.serialize(bean));//覆盖，不用成为僵尸了。
						jedis.expire(key.getBytes(), 360000);
					}
					
				}
				return result;
			}
		}.exec();
		
		
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			String result = null;
//			if(redis.exists(key.getBytes())){
//				if(bean.getUsingKeys().isEmpty()){//无效对象
//					if(redis.exists(key.getBytes())){
//						redis.del(key.getBytes());
//					}
//				}else{
//					bean.setCheckTime(System.currentTimeMillis());
//					result = redis.set(key.getBytes(), SerializeUtil.serialize(bean));//覆盖，不用成为僵尸了。
//					redis.expire(key.getBytes(), 360000);
//				}
//				
//			}
//			return result;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}
	/**
	 * 0:删除;1:覆盖;-1:啥都不做
	 * @param jedis
	 * @param tran
	 * @param key
	 * @param bean
	 * @throws Exception
	 */
	public int beforeUpdate(final String key,final AbstractStoreBean bean) throws PiRedisExecption{
		return new RedisExecutor<Integer>() {
			@Override
			public Integer run() throws Exception {
				if(jedis.exists(key.getBytes())){
					if(bean.getUsingKeys().isEmpty()){//无效对象
						if(jedis.exists(key.getBytes())){
//							jedis.del(key.getBytes());
							return 0;
						}
					}else{
//						bean.setCheckTime(System.currentTimeMillis());
//						tran.set(key.getBytes(), SerializeUtil.serialize(bean));//覆盖，不用成为僵尸了。
//						tran.expire(key.getBytes(), 360000);
						return 1;
					}
					
				}
				return -1;
			}
		}.exec();
		
//		Jedis jedis = null;
//		try{
//			if(jedis==null){
//				jedis = this.getRedis();
//			}
//			if(jedis.exists(key.getBytes())){
//				if(bean.getUsingKeys().isEmpty()){//无效对象
//					if(jedis.exists(key.getBytes())){
////						jedis.del(key.getBytes());
//						return 0;
//					}
//				}else{
////					bean.setCheckTime(System.currentTimeMillis());
////					tran.set(key.getBytes(), SerializeUtil.serialize(bean));//覆盖，不用成为僵尸了。
////					tran.expire(key.getBytes(), 360000);
//					return 1;
//				}
//				
//			}
//			return -1;
//		}catch(Exception e){
//			pool.returnBrokenResource(jedis);
//			throw new RuntimeException(e);
//		}finally{
//			if(jedis!=null)this.pool.returnResource(jedis);
//		}
	}
	
	public void set(@NotNull Transaction tran,String key, AbstractStoreBean value) throws Exception {
		try{
			byte[] bkey = key.getBytes();
			 tran.setnx(bkey, SerializeUtil.serialize(value));
			tran.expire(bkey, 3600000);//一个钟如果不更新过期,说明他没有再线程再验证了，成僵尸了。自动删除。
		}finally{
			
		}
	}
	

	public Long set(final String key,final AbstractStoreBean value) throws PiRedisExecption {
		return new RedisExecutor<Long>() {
			@Override
			public Long run() throws Exception {
				byte[] bkey = key.getBytes();
				Long result = jedis.setnx(bkey, SerializeUtil.serialize(value));
				jedis.expire(bkey, 3600000);//一个钟如果不更新过期,说明他没有再线程再验证了，成僵尸了。自动删除。
				return result;
			}
		}.exec();
		
		
//		Jedis redis = null;
//		try{
//			redis = getRedis();
//			byte[] bkey = key.getBytes();
//			Long result = redis.setnx(bkey, SerializeUtil.serialize(value));
//			redis.expire(bkey, 3600000);//一个钟如果不更新过期,说明他没有再线程再验证了，成僵尸了。自动删除。
//			return result;
//		}catch(Exception e){
//			pool.returnBrokenResource(redis);
//			throw new RuntimeException(e);
//		}finally{
//			pool.returnResource(redis);
//		}
	}


	public void remove(@NotNull Transaction tran,String key) throws Exception {
		try{
			tran.del(key.getBytes());
		}finally{
			
		}
	}

	
	

//	public Set<K> keySet() throws Exception {
//		Jedis redis = null;
//		try{
//			Set<K> result = new HashSet<K>();
//			redis = getRedis();
//			Set<byte[]> set = redis.hkeys(mapName.getBytes());
//			for(byte[] key :set){
//				result.add((K)SerializeUtil.unserialize(key));
//			}
//			return result;
//		}finally{
//			pool.returnResource(redis);
//		}
//	}

//	public Collection<V> values() throws Exception {
//		Jedis redis = null;
//		try{
//			Set<V> result = new HashSet<V>();
//			redis = getRedis();
//			 java.util.List<byte[]> list = redis.hvals(mapName.getBytes());
//			for(byte[] val :list){
//				result.add((V)SerializeUtil.unserialize(val));
//			}
//			return result;
//		}finally{
//			pool.returnResource(redis);
//		}
//	}

}
